﻿namespace NTLib.Pipe.Providers
{
    using NTLib.Core.Component;
    using NTLib.Pipe.Descriptors;
    using NTLib.Pipe.Targets;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;


    /// <summary>
    /// Routing interface used to define the way to connect to target
    /// </summary>
    public interface IPipeProvider : IComponent
    {
        #region Methods

        /// <summary>
        /// Determines whether this instance can managed target the specified target.
        /// </summary>
        /// <param name="desc">Target description used to define the target.</param>
        /// <returns><c>true</c> if the provider can managed the specific target.</returns>
        Task<bool> CanManagedTargetAsync(ITargetDescriptor desc, CancellationToken token = default(CancellationToken));

        /// <summary>
        /// Determines whether this instance can get the pipe refert by the specified identifier.
        /// </summary>
        /// <param name="Id">The identifier.</param>
        /// <returns><c>true</c> if the pipe can be get by this provider.</returns>
        Task<bool> CanGetPipeAsync(Guid Id, CancellationToken token = default(CancellationToken));

        /// <summary>
        /// Creates asynchronously the pipe in function of the target.
        /// </summary>
        /// <typeparam name="T">Type of the object that will travel through the pipe.</typeparam>
        /// <param name="target">The target description used to construct properly the pipe.</param>
        /// <returns>Pipe object used to transfert data.</returns>
        Task<IPipeManipulatorOwner<T>> CreateAsync<T>(PipeType type, ITargetDescriptor target, CancellationToken token = default(CancellationToken));

        /// <summary>
        /// Gets the other side of the pipe from the pipe ID.
        /// </summary>
        /// <typeparam name="T">Type object that will travel through the pipe</typeparam>
        /// <param name="pipeId">The pipe identifier.</param>
        /// <returns>Return asynchrounously the other side of the pipe from the pipe ID</returns>
        Task<IPipeManipulator<T>> GetPipeAsync<T>(Guid pipeId, CancellationToken token = default(CancellationToken));


        #endregion
    }
}
